<?php
/**
 * File: ProjectController.class.php
 * Author: camy <375766145@qq.com>
 * Time: 2018/3/17 23:41
 */

namespace Home\Controller;

use Common\Service\Check;
use Common\Service\Project;
use Common\Service\ProjectPoints;

/**
 * 项目管理
 * @package Home\Controller
 */
class ProjectController extends BaseController
{
    /**
     * 项目列表页面
     * @desc page-get
     * @param string $search 搜索参数
     * @param int $status 状态|no|0-进行中，1-结束
     * @param int $page 页数
     * @return string list[].name 项目名称
     * @return string list[].amount 项目金额
     * @return string list[].created_at 项目金额
     * @request /project/index
     */
    public function index($search = '', $status = 0)
    {
        $this->title = '项目列表';
        $service = Project::instance();
        $data = $service->getProjectList($search, $status);
        $this->assign('data', $data);
        $this->render();
    }

    /**
     * 项目详情页面
     * @desc page-get
     * @param int $id 项目id|yes
     * @return string name 项目名称
     * @return string content 项目内容
     * @return string summary 项目总结
     * @return string amount 项目金额
     * @return string begin_time 计划开工日期
     * @return string end_time 计划竣工日期
     * @return string detail_address 项目地址
     * @return string province 省
     * @return string city 市
     * @return string area 区
     * @return string address 项目地址
     * @return float pre_points 可分配预计积分总额
     * @return float points 可分配实际积分余额
     * @return int status 项目状态:0-进行中，1-已结束，2-已删除
     * @return string manager 项目负责人名字
     * @return string schedules[].schedule 项目进度
     * @return string schedules[].updated_at 项目进度更新时间
     * @return string created_at
     * @return string updated_at
     * @request /project/detail
     */
    public function detail($id)
    {
        $this->title = '项目详情';
        //TODO 权限
        $service = Project::instance();
        $data = $service->getProjectDetail(intval($id));
        //项目不存在
        if (!$data) {
            $this->fail($service->error);
        }
        $this->assign('data', $data);
        $this->render();
    }

    /**
     * 创建项目
     * @desc ajax-post
     * @param string $name 项目名称|yes
     * @param float $amount 项目金额|yes
     * @param string $content 项目内容|yes
     * @param int $user_id 项目管理员id|yes
     * @param string $begin_time 计划开工日期|yes
     * @param string $end_time 计划竣工日期|yes
     * @param int $province 省|yes
     * @param int $city 市|yes
     * @param int $area 区|yes
     * @param string $address 详细地址|yes
     * @request /project/create
     * @return  int id 返回id
     */
    public function create()
    {
        //TODO 权限
        $post = $_POST;
        $managerId = $post['user_id'];
        unset($post['user_id']);
        $projectData = $post;
        $service = Project::instance();
        $returnId = $service->createProject($projectData, intval($managerId));
        if (!$returnId) {
            return $this->jsonFail($service->error);
        }
        //通知项目负责人
        $msgParam['project_id'] = $returnId;
        $msgParam['user_id'] = $managerId;
        notification('project', 'createProject', $msgParam);
        return $this->jsonSuccess(['id' => $returnId]);
    }

    /**
     * 更新项目
     * @desc ajax-post
     * @param int $id |项目id|yes
     * @param string $name 项目名称|yes
     * @param float $amount 项目金额|yes
     * @param string $content 项目内容|yes
     * @param string $begin_time 计划开工日期|yes
     * @param string $end_time 计划竣工日期|yes
     * @param int $province 省|yes
     * @param int $city 市|yes
     * @param int $area 区|yes
     * @param string $address 详细地址|yes
     * @return int id 返回id
     * @request /project/update
     */
    public function update()
    {
        $post = $_POST;
        //TODO 权限
        $service = Project::instance();
        $res = $service->updateProject($post);
        if (!$res) {
            return $this->jsonFail($service->error);
        }
        return $this->jsonSuccess(['id' => $post['id']]);
    }

    /**
     * 删除项目
     * @desc ajax-post
     * @param int $id 项目id|yes
     * @request /project/delete
     */
    public function delete()
    {
        $post = $_POST;
        //TODO 权限
        $data['id'] = intval($post['id']);
        $data['deleted_at'] = my_format_time();
        $res = M('project')->save($data);
        if (!$res) {
            return $this->jsonFail('删除项目失败');
        }
        notification('project', 'deleteProject', ['project_id' => $data['id']]);
        return $this->jsonSuccess();

    }

    /**
     * 添加项目进度
     * @desc ajax-post
     * @param int $project_id 项目id|yes
     * @param string $schedule 项目进度|yes
     * @return  int id 返回id
     * @request /project/addSchedule
     */
    public function addSchedule()
    {
        $post = $_POST;
        if (empty($post['schedule'])) {
            return $this->jsonFail('项目进度不能为空');
        }
        //TODO 权限
        $data['project_id'] = $post['project_id'];
        $data['schedule'] = strval($post['schedule']);
        $data['user_id'] = user()->id;
        $returnId = M('projectSchedule')->add($data);
        if (!$returnId) {
            return $this->jsonFail('项目进度添加失败');
        }
        return $this->jsonSuccess(['id' => $returnId]);
    }


    /**
     * 获取项目成员
     * @desc ajax-get
     * @param int $project_id 项目id|yes
     * @param int $user_type 成员类型|no|0-普通成员,1-专业负责人,2-项目负责人（为空返回所有成员）
     * @return int [].id 项目成员表id
     * @return int [].type 项目成员类型：0-普通成员,1-专业负责人,2-项目负责人
     * @return string [].remark 成员备注
     * @return string [].name 用户名
     * @return string [].avatar 用户头像
     * @return string [].department 用户部门
     * @return string [].position 用户职位
     * @request /project/getMember
     */
    public function getMember($project_id, $user_type = null)
    {
        //TODO 权限
        $service = Project::instance();
        $res = $service->getProjectMember(intval($project_id), $user_type);
        return $this->jsonSuccess($res);
    }

    /**
     * 添加项目成员
     * @desc ajax-post
     * @param int $project_id 项目id|yes
     * @param int $user_id 用户id|yes
     * @param string $remark 成员备注|no
     * @return int id 返回id
     * @request /project/addMember
     */
    public function addMember()
    {
        $post = $_POST;
        //TODO 权限
        $service = Project::instance();
        $returnId = $service->addProjectMember(
            intval($post['project_id']),
            intval($post['user_id']),
            strval($post['remark'])
        );
        if (!$returnId) {
            return $this->jsonFail($service->error);
        }
        //通知成员
        notification('project', 'addMember', $post);
        return $this->jsonSuccess(['id' => $returnId]);

    }

    /**
     * 更新项目成员
     * @desc ajax-post
     * @param int $id 项目成员表id|yes
     * @param string $remark 成员备注|yes
     * @return int id 返回id
     * @request /project/updateMember
     */
    public function updateMember()
    {
        $post = $_POST;
        $member = M('projectMember')->find(intval($post['id']));
        if (!$member) {
            return $this->jsonFail('项目成员不存在');
        }
        //TODO 权限
        $data['id'] = intval($post['id']);
        $data['user_remark'] = strval($post['remark']);
        $res = M('projectMember')->save($data);
        if (!$res) {
            return $this->jsonFail('更新项目成员失败');
        }
        return $this->jsonSuccess(['id' => $post['id']]);

    }

    /**
     * 删除项目成员
     * @desc ajax-post
     * @param int $id 项目成员表id|yes
     * @request /project/deleteMember
     */
    public function deleteMember()
    {
        $post = $_POST;
        $member = M('projectMember')->find(intval($post['id']));
        if (!$member) {
            return $this->jsonFail('项目成员不存在');
        }
        //TODO 权限
        $service = Project::instance();
        $res = $service->deleteProjectMember(intval($post['id']));
        if (!$res) {
            return $this->jsonFail($service->error);
        }
        //通知成员
        notification('project', 'deleteMember', $post);
        return $this->jsonSuccess();

    }

    /**
     * 分配积分页面
     * @desc page-get
     * @param int $project_id 所属项目|yes
     * @param int $type 积分类型|yes|0-预计积分，1-实际积分
     * @return float points 可分配积分
     * @return  string allocates[].id 分配id
     * @return  string allocates[].serial 分配编号
     * @return  int allocates[].status 分配状态：：0-分配中，1-已完成，2-申述
     * @return  float allocates[].points 分配积分数
     * @return  string allocates[].updated_at 分配日期
     * @request /project/points
     */
    public function points($project_id, $type)
    {
        //TODO 权限
        $user = user();
        if (!in_array($type, [0, 1])) {
            return $this->jsonFail('分配类型错误');
        }
        if ($type == 1) {
            $this->title = '实际积分分配';
            //可分配实际积分
            $points = $user->points;
        } else {
            $this->title = '预计积分分配';
            //可分配预计积分
            $points = $user->pre_points;
        }
        $allocates = M('projectPointsAllocate')
            ->field('id,serial,status,points,updated_at')
            ->where(['project_id' => $project_id, 'allocate_user_id' => $user->id, 'points_type' => $type])
            ->order('updated_at desc')
            ->select();
        $data['points'] = $points;
        $data['allocates'] = $allocates;
        $this->assign('data', $data);
        return $this->render();
    }

    /**
     * 获取积分分配详情
     * @desc ajax-get
     * @param int $project_id 所属项目|yes
     * @param int $type 分配类型|yes|0-预计积分，1-实际积分
     * @param int $allocate_id 分配表id(重要)|yes|0代表新增分配,非0代表重新分配
     * @return float points 可分配积分
     * @return int members[].user_id 成员用户id
     * @return int members[].type 成员类型：0-普通成员,1-专业负责人,2-项目负责人
     * @return string members[].name 成员名称
     * @return string members[].avatar 成员头像
     * @return string members[].department 成员部门
     * @return string members[].position 成员头像
     * @return string members[].remark 成员备注
     * @return int members[].allocate_record_id 分配记录id（0表示未分配）
     * @return int members[].allocate_status 成员分配状态：0-未分配,1-已分配,2-重新分配
     * @return float members[].allocate_points 成员已分配积分数
     * @return string members[].allocate_reason 申述原因
     * @request /project/getAllocateParam
     */
    public function getAllocateParam($project_id, $type, $allocate_id)
    {
        //TODO 权限
        if (!in_array($type, [0, 1])) {
            return $this->jsonFail('分配类型错误');
        }
        $service = ProjectPoints::instance();
        if ($allocate_id == 0) {
            $res = $service->getAddAllocateParam($project_id, $type);
        } else {
            $res = $service->getAllocateParam($allocate_id);
        }
        if (!$res) {
            return $this->jsonFail($service->error);
        }
        return $this->jsonSuccess($res);
    }

    /**
     * 新增/重新 分配积分
     * @desc ajax-post
     * @param int $project_id 所属项目|yes
     * @param int $type 分配类型|yes|0-预计积分，1-实际积分
     * @param int $allocate_id 分配表id(重要)|yes|0代表新增分配
     * @param  int $members [].user_id 成员用户id|yes
     * @param  int $members [].type 成员类型|yes|0-普通成员,1-专业负责人,2-项目负责人
     * @param  int $members [].remark 成员备注|yes
     * @param  string $members [].allocate_record_id 分配记录id|yes|0代表新增分配
     * @param  float $members [].allocate_points 分配积分数|yes
     * @request /project/allocatePoints
     */
    public function allocatePoints()
    {
        $post = $_POST;
        //TODO 权限
        if (!in_array($post['type'], [0, 1])) {
            return $this->jsonFail('分配类型错误');
        }
        if (empty($post['members'])) {
            return $this->jsonFail('分配详情不能为空');
        }
        $user = user();
        //分配条件
        $userIdArr = array_column($post['members'], 'user_id');
        //分配人必须存在
        if (!in_array($user->id, $userIdArr)) {
            return $this->jsonFail('必须分配您自己的积分额');
        }
        if (count($userIdArr) < 2) {
            return $this->jsonFail('请分配至少1位项目成员');
        }
        //判断积分是否足够
        $totalPoints = array_column_sum($post['members'], 'allocate_points');
        if ($post['type'] == 1) {
            $havePoints = $user->points;
        } else {
            $havePoints = $user->pre_points;
        }
        if (($totalPoints - $havePoints) > 0) {
            return $this->jsonFail('分配积分总数大于可分配积分余额');
        }
        if ($totalPoints == 0) {
            return $this->jsonFail('您还没有没分配');
        }
        //开始分配
        try {
            $service = ProjectPoints::instance();
            M()->startTrans();
            if (empty($post['allocate_id'])) {
                //新增分配表
                $allocateId = $service->createAllocate($post['project_id'], $post['type'], $totalPoints);
                if (!$allocateId) {
                    throw  new \Exception($service->error);
                }
                //分配积分-首次分配
                foreach ($post['members'] as $member) {
                    if ($member['allocate_record_id'] != 0) {
                        throw  new \Exception('成员已分配');
                    }
                    $res = $service->addAllocateRecord(
                        $allocateId,
                        $member['allocate_points'],
                        $member['user_id'],
                        $member['type'],
                        $member['remark']
                    );
                    if (!$res) {
                        throw  new \Exception($service->error);
                    }
                }
            } else {
                //分配积分-重新分配
                foreach ($post['members'] as $member) {
                    if ($member['allocate_record_id'] == 0) {
                        throw  new \Exception('未指定分配记录');
                    }
                    $res = $service->addAllocateRecordAgain(
                        $member['allocate_record_id'],
                        $member['allocate_points']
                    );
                    if (!$res) {
                        throw  new \Exception($service->error);
                    }
                }

            }
            M()->commit();
            //实际积分-通知成员
            if ($post['type'] == 1) {
                notification('project', 'allocatePoints', $post);
            }
            return $this->jsonSuccess();
        } catch (\Exception $e) {
            M()->rollback();
            return $this->jsonFail($e->getMessage());
        }

    }

    /**
     *  ！项目资源页面
     */
    public function attachment()
    {
        $this->title = '项目资源';
        $this->render();
    }

    /**
     * ！项目资源列表页面
     */
    public function attachmentList()
    {
        $this->title = '项目资源列表';
        $this->render();
    }


}